package com.yixiu.study.juc.threadpool;

import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask;

/**
 * @CalssName T06_ForkJoinPool
 * @Description
 * @Author yixiu
 * @Date 2021/6/29 11:05
 * @Verison 1.0
 **/
public class T06_ForkJoinPool {

    static int[] nums = new int[1000000];
    static final int MAX_NUM = 50000;
    static Random r = new Random();

    static {
        for (int i = 0; i < nums.length; i++) {
            nums[i] = r.nextInt(100);
        }
        System.out.println("---------" + Arrays.stream(nums).sum());
    }

    static class AddTask extends RecursiveAction{
        int start, end;

        public AddTask(int start, int end) {
            this.start = start;
            this.end = end;
        }

        @Override
        protected void compute() {
            if(end - start <= MAX_NUM){
                long sum = 0L;
                for(int i = start; i < end; i++){
                    sum += nums[i];
                }
                System.out.println("from: " + start + " to: " + end + " = " + sum);
            } else {
                int middle = start + (end - start)/2;
                AddTask subAddTask1 = new AddTask(start, middle);
                AddTask subAddTask2 = new AddTask(middle, end);
                subAddTask1.fork();
                subAddTask2.fork();
            }
        }
    }

    static class AddTaskRet extends RecursiveTask<Long>{
        private static final long serialVersionUID = 1L;
        int start, end;

        public AddTaskRet(int start, int end) {
            this.start = start;
            this.end = end;
        }

        @Override
        protected Long compute() {
            if(end - start <= MAX_NUM){
                long sum = 0L;
                for (int i = start; i < end; i++) {
                    sum += nums[i];
                    return sum;
                }

                int middle = start + (end - start)/2;

                AddTaskRet subTaskRet1 = new AddTaskRet(start, middle);
                AddTaskRet subTaskRet2 = new AddTaskRet(middle, end);
                subTaskRet1.fork();
                subTaskRet2.fork();

                return subTaskRet1.join() + subTaskRet2.join();
            }
            return null;
        }
    }

    public static void main(String[] args) throws IOException {
//        ForkJoinPool fjp = new ForkJoinPool();
//        AddTask task = new AddTask(0, nums.length);
//        fjp.execute(task);
//        System.in.read();

        T06_ForkJoinPool temp = new T06_ForkJoinPool();
        ForkJoinPool fjp = new ForkJoinPool();
        AddTaskRet addTaskRet = new AddTaskRet(0, nums.length);
        fjp.execute(addTaskRet);
        long result = addTaskRet.join();
        System.out.println(result);
        System.in.read();

    }

}
